package main

import (
	"fmt"
	"math"
	"strconv"
)

func main() {
	// ==========================================
	// 变量声明和初始化
	// ==========================================

	// 方法1：声明变量并赋值
	var name string = "Go语言"
	var age int = 14 // Go语言发布于2009年
	var isAwesome bool = true

	// 方法2：声明变量，Go会根据值自动推断类型
	var language = "Go"
	var version = 1.18

	// 方法3：短变量声明（仅在函数内部可用）
	shortName := "Golang"
	releaseYear := 2009

	// 多变量声明
	var (
		firstName string = "Robert"
		lastName  string = "Griesemer"
		role      string = "Go语言创始人之一"
	)

	// 多变量同时赋值
	var a, b, c int = 1, 2, 3
	x, y, z := 10, 20, "hello"

	fmt.Println("变量示例:")
	fmt.Println(name, age, isAwesome)
	fmt.Println(language, version)
	fmt.Println(shortName, releaseYear)
	fmt.Println(firstName, lastName, role)
	fmt.Println(a, b, c)
	fmt.Println(x, y, z)

	// ==========================================
	// 基本数据类型
	// ==========================================

	// 整数类型
	var intNum int = 42                      // 根据系统架构可能是32位或64位
	var int8Num int8 = 127                   // -128 到 127
	var int16Num int16 = 32767               // -32768 到 32767
	var int32Num int32 = 2147483647          // -2147483648 到 2147483647
	var int64Num int64 = 9223372036854775807 // -9223372036854775808 到 9223372036854775807

	// 无符号整数
	var uintNum uint = 42                       // 根据系统架构可能是32位或64位
	var uint8Num uint8 = 255                    // 0 到 255
	var uint16Num uint16 = 65535                // 0 到 65535
	var uint32Num uint32 = 4294967295           // 0 到 4294967295
	var uint64Num uint64 = 18446744073709551615 // 0 到 18446744073709551615

	// 浮点数类型
	var float32Num float32 = 3.14159265358979323846 // 单精度浮点数
	var float64Num float64 = 3.14159265358979323846 // 双精度浮点数

	// 复数类型
	var complex64Num complex64 = 1 + 2i
	var complex128Num complex128 = complex(3, 4)

	// 字符类型
	var char byte = 'A'  // byte是uint8的别名，用于表示ASCII字符
	var char2 rune = '中' // rune是int32的别名，用于表示Unicode字符

	// 布尔类型
	var isTrue bool = true
	var isFalse bool = false

	// 字符串类型
	var str string = "Hello, Go!"
	var multiLine string = `这是一个
多行字符串
支持换行`

	fmt.Println("\n基本数据类型示例:")
	fmt.Printf("int: %d, 类型: %T\n", intNum, intNum)
	fmt.Printf("int8: %d, 类型: %T\n", int8Num, int8Num)
	fmt.Printf("int16: %d, 类型: %T\n", int16Num, int16Num)
	fmt.Printf("int32: %d, 类型: %T\n", int32Num, int32Num)
	fmt.Printf("int64: %d, 类型: %T\n", int64Num, int64Num)

	fmt.Printf("uint: %d, 类型: %T\n", uintNum, uintNum)
	fmt.Printf("uint8: %d, 类型: %T\n", uint8Num, uint8Num)
	fmt.Printf("uint16: %d, 类型: %T\n", uint16Num, uint16Num)
	fmt.Printf("uint32: %d, 类型: %T\n", uint32Num, uint32Num)
	fmt.Printf("uint64: %d, 类型: %T\n", uint64Num, uint64Num)

	fmt.Printf("float32: %f, 类型: %T\n", float32Num, float32Num)
	fmt.Printf("float64: %f, 类型: %T\n", float64Num, float64Num)

	fmt.Printf("complex64: %v, 类型: %T\n", complex64Num, complex64Num)
	fmt.Printf("complex128: %v, 类型: %T\n", complex128Num, complex128Num)

	fmt.Printf("byte: %c (%d), 类型: %T\n", char, char, char)
	fmt.Printf("rune: %c (%d), 类型: %T\n", char2, char2, char2)

	fmt.Printf("bool true: %t, 类型: %T\n", isTrue, isTrue)
	fmt.Printf("bool false: %t, 类型: %T\n", isFalse, isFalse)

	fmt.Printf("string: %s, 类型: %T\n", str, str)
	fmt.Printf("多行字符串: \n%s\n", multiLine)

	// 零值（未初始化的变量的默认值）
	var zeroInt int
	var zeroFloat float64
	var zeroBool bool
	var zeroString string
	var zeroPointer *int

	fmt.Println("\n零值示例:")
	fmt.Printf("int零值: %d\n", zeroInt)
	fmt.Printf("float零值: %f\n", zeroFloat)
	fmt.Printf("bool零值: %t\n", zeroBool)
	fmt.Printf("string零值: %q\n", zeroString)
	fmt.Printf("指针零值: %v\n", zeroPointer)

	// ==========================================
	// 常量
	// ==========================================

	// 常量声明
	const Pi = 3.14159
	const (
		StatusOK       = 200
		StatusNotFound = 404
	)

	// 使用iota创建枚举常量
	const (
		Sunday    = iota // 0
		Monday           // 1
		Tuesday          // 2
		Wednesday        // 3
		Thursday         // 4
		Friday           // 5
		Saturday         // 6
	)

	// iota更复杂的用法
	const (
		_  = iota             // 忽略第一个值
		KB = 1 << (10 * iota) // 1 << 10 = 1024
		MB                    // 1 << 20 = 1048576
		GB                    // 1 << 30 = 1073741824
		TB                    // 1 << 40 = 1099511627776
	)

	fmt.Println("\n常量示例:")
	fmt.Printf("Pi: %f\n", Pi)
	fmt.Printf("StatusOK: %d, StatusNotFound: %d\n", StatusOK, StatusNotFound)
	fmt.Printf("星期几: %d %d %d %d %d %d %d\n", Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)
	fmt.Printf("KB: %d, MB: %d, GB: %d, TB: %d\n", KB, MB, GB, TB)

	// ==========================================
	// 运算符
	// ==========================================

	// 算术运算符
	sum := 10 + 5       // 加法
	diff := 10 - 5      // 减法
	product := 10 * 5   // 乘法
	quotient := 10 / 3  // 整数除法（结果为整数）
	remainder := 10 % 3 // 取余

	// 浮点数除法
	floatQuotient := 10.0 / 3.0

	// 自增和自减
	count := 0
	count++ // 等同于 count = count + 1
	count-- // 等同于 count = count - 1

	// 关系运算符
	isEqual := 10 == 10
	isNotEqual := 10 != 5
	isGreater := 10 > 5
	isLess := 10 < 20
	isGreaterOrEqual := 10 >= 10
	isLessOrEqual := 5 <= 5

	// 逻辑运算符
	andResult := true && false // 逻辑与
	orResult := true || false  // 逻辑或
	notResult := !true         // 逻辑非

	// 位运算符
	bitwiseAnd := 12 & 5     // 按位与: 1100 & 0101 = 0100 (4)
	bitwiseOr := 12 | 5      // 按位或: 1100 | 0101 = 1101 (13)
	bitwiseXor := 12 ^ 5     // 按位异或: 1100 ^ 0101 = 1001 (9)
	bitwiseComplement := ^12 // 按位取反: ^1100 = ...11110011 (-13)
	leftShift := 12 << 2     // 左移: 1100 << 2 = 110000 (48)
	rightShift := 12 >> 2    // 右移: 1100 >> 2 = 11 (3)

	// 赋值运算符
	var value = 10
	value += 5 // 等同于 value = value + 5
	value -= 3 // 等同于 value = value - 3
	value *= 2 // 等同于 value = value * 2
	value /= 4 // 等同于 value = value / 4
	value %= 3 // 等同于 value = value % 3

	fmt.Println("\n运算符示例:")
	fmt.Printf("算术运算: %d + %d = %d, %d - %d = %d, %d * %d = %d, %d / %d = %d, %d %% %d = %d\n",
		10, 5, sum, 10, 5, diff, 10, 5, product, 10, 3, quotient, 10, 3, remainder)
	fmt.Printf("浮点数除法: %.2f\n", floatQuotient)
	fmt.Printf("自增后的count: %d\n", count)

	fmt.Printf("关系运算: 10 == 10: %t, 10 != 5: %t, 10 > 5: %t, 10 < 20: %t, 10 >= 10: %t, 5 <= 5: %t\n",
		isEqual, isNotEqual, isGreater, isLess, isGreaterOrEqual, isLessOrEqual)

	fmt.Printf("逻辑运算: true && false: %t, true || false: %t, !true: %t\n",
		andResult, orResult, notResult)

	fmt.Printf("位运算: 12 & 5 = %d, 12 | 5 = %d, 12 ^ 5 = %d, ^12 = %d, 12 << 2 = %d, 12 >> 2 = %d\n",
		bitwiseAnd, bitwiseOr, bitwiseXor, bitwiseComplement, leftShift, rightShift)

	fmt.Printf("赋值运算后的value: %d\n", value)

	// ==========================================
	// 类型转换
	// ==========================================

	// 数值类型之间的转换
	var integer int = 42
	var float float64 = float64(integer)
	var unsignedInt uint = uint(integer)
	var int32Val int32 = int32(integer)

	// 字符串与数值之间的转换
	var intStr string = strconv.Itoa(integer) // int转string
	parsedInt, err := strconv.Atoi(intStr)    // string转int
	if err != nil {
		fmt.Println(err)
	}

	floatStr := strconv.FormatFloat(math.Pi, 'f', 2, 64)  // float转string，保留2位小数
	parsedFloat, err1 := strconv.ParseFloat(floatStr, 64) // string转float
	if err1 != nil {
		fmt.Println(err1)
	}

	// 字符串与字节切片之间的转换
	var helloStr string = "Hello, 世界"
	var bytes []byte = []byte(helloStr)     // string转[]byte (ASCII)
	var runes []rune = []rune(helloStr)     // string转[]rune (Unicode)
	var backToString string = string(bytes) // []byte转string
	var runeToString string = string(runes) // []rune转string

	fmt.Println("\n类型转换示例:")
	fmt.Printf("int转其他类型: int(%d) -> float64(%.1f), uint(%d), int32(%d)\n",
		integer, float, unsignedInt, int32Val)

	fmt.Printf("int与string转换: int(%d) <-> string(%s) -> int(%d)\n",
		integer, intStr, parsedInt)

	fmt.Printf("float与string转换: float64(%f) -> string(%s) -> float64(%f)\n",
		math.Pi, floatStr, parsedFloat)

	fmt.Printf("string与[]byte转换: %s -> %v -> %s\n",
		helloStr, bytes, backToString)

	fmt.Printf("string与[]rune转换: %s -> %v -> %s\n",
		helloStr, runes, runeToString)

	// ==========================================
	// 练习
	// ==========================================

	// 1. 声明一个名为myAge的变量，并赋值为你的年龄
	// 2. 声明一个常量PI，值为3.14159
	// 3. 计算圆的面积，半径为5.0
	// 4. 将浮点数面积转换为整数，并打印结果
	// 5. 创建一个包含三个不同数据类型的变量，并使用fmt.Printf打印它们的值和类型
}
